//! 执行器创建者 trait 实现

use sgs_core::preclude::*;

use crate::{
    error::PatternNotFoundError,
    random_list,
    utils::{count::CycleCounter, HeadShuffle},
};

use super::{Executor, State};

/// 执行器创建者 trait
pub trait Execute {
    /// 设置 pattern 编号，创建启动器
    fn executor(&self, pattern_index: usize) -> Result<Executor, PatternNotFoundError>;
}

impl Execute for crate::pkg::Package {
    fn executor(&self, pattern_index: usize) -> Result<Executor, PatternNotFoundError> {
        match self.patterns.get(pattern_index) {
            Some(pattern) => {
                let cards = random_list!(self.cards.len());
                let players_count = pattern.identity_list.len();

                Ok(Executor {
                    tag: &self.tag,
                    desp: &self.desp,
                    cards: &self.cards,
                    roles: &self.roles,
                    pkg_name: &self.name,
                    version: &self.version,
                    pattern_name: &pattern.name,
                    delegators: &self.delegators,
                    state: State::new(cards, players_count),
                    players: pattern
                        .identity_list
                        .shuffle_keep_head()
                        .into_iter()
                        .enumerate()
                        .map(|(index, identity)| Player {
                            index,
                            identity,
                            next: index.next(players_count),
                            ..Default::default()
                        })
                        .collect(),
                })
            }
            None => Err(PatternNotFoundError {
                index: pattern_index,
                name: self.name.clone(),
            }),
        }
    }
}
